package com.ruoyi.common.utils.http;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

@Component
public class HttpClientUtil {

    private static final Log logeer = LogFactory.getLog(HttpClientUtil.class);


    public static HttpResponse postJson(String path, String json, String charset) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = HttpClientBuilder.create().build();
            httpPost = new HttpPost(path.replaceAll("(?<!:)/{2,}", "/"));
            StringEntity entity = new StringEntity(json, charset);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            return response;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }


    public static String doGet(String url, Map<String, Object> map, String charset, Header[] headers) {
        if (ObjectUtils.isNotEmpty(map)) {
            url = url + "?" + mapToUrlStr(map);
        }
        logeer.info("*****url:  " + url);
        String result = "";
        try {
            // 根据地址获取请求
            url = url.replaceAll("(?<!:)/{2,}", "/");
            url = url.replaceAll(" ", "%20");
            //发送方报错后用这个转一下
            HttpGet request = new HttpGet(url);// 这里发送get请求
            if (headers != null) {
                for (Header header : headers) {
                    request.addHeader(header);
                }
            }

            // 获取当前客户端对象
            HttpClient httpClient = HttpClientBuilder.create().build();


            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), charset);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logeer.info("*****result:  " + result);
        return result;
    }

    /**
     * 带检查url的get请求(含请求头)
     *
     * @param domain  域名
     * @param api     接口名
     * @param map     请求参数
     * @param charset 字符编码
     * @param headers 请求头
     * @return
     */
    public static String doGet(String domain, String api, Map<String, Object> map, String charset, Header[] headers) {
        String url = CommonFunc.checkDomainUrl(domain, api);
        url = url + "?" + mapToUrlStr(map);
        logeer.info("*****url:  " + url);
        String result = "";
        try {
            // 根据地址获取请求
            url = url.replaceAll("(?<!:)/{2,}", "/");
            url = url.replaceAll(" ", "%20");
            //发送方报错后用这个转一下
            HttpGet request = new HttpGet(url);// 这里发送get请求
            if (headers != null) {
                for (Header header : headers) {
                    request.addHeader(header);
                }
            }

            // 获取当前客户端对象
            HttpClient httpClient = HttpClientBuilder.create().build();


            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), charset);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logeer.info("*****result:  " + result);
        return result;
    }


    public static String doPost(String url, String str, String charset, Header[] headers) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = HttpClientBuilder.create().build();
            httpPost = new HttpPost(url.replaceAll("(?<!:)/{2,}", "/"));
            StringEntity entity = new StringEntity(str, charset);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            if (headers != null) {
                for (Header header : headers) {
                    httpPost.addHeader(header);
                }
            }
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * 带检查url的post请求(含请求头)
     *
     * @param domain  域名
     * @param api     接口名
     * @param str     请求参数
     * @param charset 字符编码(UTF-8)
     * @param headers 请求头
     * @return
     */
    public static String doPost(String domain, String api, String str, String charset, Header[] headers) {
        String url = CommonFunc.checkDomainUrl(domain, api);
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = HttpClientBuilder.create().build();
            httpPost = new HttpPost(url.replaceAll("(?<!:)/{2,}", "/"));
            StringEntity entity = new StringEntity(str, charset);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            if (headers != null) {
                for (Header header : headers) {
                    httpPost.addHeader(header);
                }
            }
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    public static String doPost(String url, String str, String charset) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = HttpClientBuilder.create().build();
            httpPost = new HttpPost(url.replaceAll("(?<!:)/{2,}", "/"));
            StringEntity entity = new StringEntity(str, charset);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }


    /**
     * 带检查参数的post请求
     *
     * @param domain  域名
     * @param api     接口名
     * @param str     请求参数
     * @param charset 字符编码(UTF-8)
     * @return
     */
    public static String doPost(String domain, String api, String str, String charset) {
        String url = CommonFunc.checkDomainUrl(domain, api);
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = HttpClientBuilder.create().build();
            httpPost = new HttpPost(url.replaceAll("(?<!:)/{2,}", "/"));
            StringEntity entity = new StringEntity(str, charset);
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * get请求
     *
     * @param url
     * @param map
     * @param charset
     * @return
     */
    public static String doGet(String url, Map<String, Object> map, String charset) {
        url = url + "?" + mapToUrlStr(map);
        logeer.info("*****url:  " + url);
        String result = "";
        try {
            url = url.replaceAll("(?<!:)/{2,}", "/");
            url = url.replaceAll(" ", "%20");
            // 根据地址获取请求
            HttpGet request = new HttpGet(url);// 这里发送get请求
            // 获取当前客户端对象
            HttpClient httpClient = HttpClientBuilder.create().build();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), charset);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logeer.info("*****result:  " + result);
        return result;
    }


    /**
     * 带检查url的get请求
     *
     * @param domain  域名
     * @param api     接口名
     * @param map     请求参数
     * @param charset 字符编码(UTF-8)
     * @return
     */
    public static String doGet(String domain, String api, Map<String, Object> map, String charset) {
        String url = CommonFunc.checkDomainUrl(domain, api);
        url = url + "?" + mapToUrlStr(map);
        logeer.info("*****url:  " + url);
        String result = "";
        try {
            url = url.replaceAll("(?<!:)/{2,}", "/");
            url = url.replaceAll(" ", "%20");
            // 根据地址获取请求
            HttpGet request = new HttpGet(url);// 这里发送get请求
            // 获取当前客户端对象
            HttpClient httpClient = HttpClientBuilder.create().build();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), charset);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logeer.info("*****result:  " + result);
        return result;
    }


    private static String mapToUrlStr(Map<String, Object> map) {
        StringBuilder stringBuilder = new StringBuilder();
        Set<String> keys = map.keySet();
        for (String string : keys) {
            if (ObjectUtils.isNotEmpty(map.get(string))) {
                Object value = map.get(string);
                if (value instanceof Collection) {
                    Collection array = (Collection) value;
                    array.forEach(index -> {
                        stringBuilder.append("&" + string + "[]" + "=" + index);
                    });
                }
                if (isBaseType(value)) {
                    stringBuilder.append("&" + string + "=" + value);
                }
            }
        }
        if (stringBuilder.toString().length() > 0) {
            return stringBuilder.toString().substring(1);
        }
        return stringBuilder.toString();
    }


    /**
     * 判断object是否为基本类型(不为对象)
     *
     * @param object
     * @return
     */
    public static boolean isBaseType(Object object) {
        Class className = object.getClass();
        if (className.equals(java.lang.Integer.class) ||
                className.equals(java.lang.Byte.class) ||
                className.equals(java.lang.Long.class) ||
                className.equals(java.lang.Double.class) ||
                className.equals(java.lang.Float.class) ||
                className.equals(java.lang.Character.class) ||
                className.equals(java.lang.String.class) ||
                className.equals(java.lang.Short.class) ||
                className.equals(java.lang.Boolean.class)) {
            return true;
        }
        return false;
    }

    /**
     * 网上获取文件
     *
     * @param savepath 保存路径
     * @param resurl   资源路径
     * @param fileName 自定义资源名
     * @return false:文件已存在 true：文件获取成功
     */
    public static boolean getInternetRes(String savepath, String resurl, String fileName) {
        URL url = null;
        HttpURLConnection con = null;
        InputStream in = null;
        FileOutputStream out = null;
        try {
            url = new URL(resurl);
            //建立http连接，得到连接对象
            con = (HttpURLConnection) url.openConnection();
            //con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            in = con.getInputStream();
            byte[] data = getByteData(in);//转化为byte数组

            File file = new File(savepath);
            if (!file.exists()) {
                file.mkdirs();
            }

            File res = new File(file + File.separator + fileName);
            if (res.exists()) {
                return false;
            }
            out = new FileOutputStream(res);
            out.write(data);
            logeer.info("downloaded successfully!");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
                if (null != in) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return true;
    }

    public static InputStream getInputStreamFromUrl(String resurl) {
        URL url = null;
        HttpURLConnection con = null;
        InputStream in = null;
        FileOutputStream out = null;

        try {
            url = new URL(resurl);
            con = (HttpURLConnection) url.openConnection();
            return con.getInputStream();
        } catch (Exception e) {
            throw new RuntimeException("资源加载错误");
        }
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param in
     * @return
     * @throws IOException
     */
    private static byte[] getByteData(InputStream in) throws IOException {
        byte[] b = new byte[1024];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len = 0;
        while ((len = in.read(b)) != -1) {
            bos.write(b, 0, len);
        }
        if (null != bos) {
            bos.close();
        }
        return bos.toByteArray();
    }


    public static HttpResponse get(String url, Map<String, Object> map, String charset) {

        url = url + "?" + mapToUrlStr(map);
        logeer.info("*****url:  " + url);
        String result = "";
        try {
            // 根据地址获取请求
            HttpGet request = new HttpGet(url.replaceAll("(?<!:)/{2,}", "/"));// 这里发送get请求
            // 获取当前客户端对象
            HttpClient httpClient = HttpClientBuilder.create().build();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


}
